home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / CalculatorWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  25.9 KB  |  875 lines  |  [TEXT/KAHL]

  1. /* CalculatorWindow.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "CalculatorWindow.h"
  31. #include "Screen.h"
  32. #include "TextEdit.h"
  33. #include "Memory.h"
  34. #include "MainWindowStuff.h"
  35. #include "GrowIcon.h"
  36. #include "Main.h"
  37. #include "SimpleButton.h"
  38. #include "Alert.h"
  39. #include "CodeCenter.h"
  40. #include "PcodeStack.h"
  41. #include "PcodeSystem.h"
  42. #include "DataMunging.h"
  43. #include "Numbers.h"
  44. #include "FixedPoint.h"
  45. #include "WindowDispatcher.h"
  46. #include "GlobalWindowMenuList.h"
  47. #include "FunctionCode.h"
  48. #include "CompilerRoot.h"
  49. #include "PcodeDisassembly.h"
  50. #include "DisassemblyWindow.h"
  51.  
  52.  
  53. #define WINDOWLEFT (30)
  54. #define WINDOWTOP (30)
  55. #define WINDOWWIDTH (450)
  56. #define WINDOWHEIGHT (200)
  57.  
  58. #define BUTTONLEFT (10)
  59. #define BUTTONTOP (2)
  60. #define BUTTONWIDTH (120)
  61. #define BUTTONHEIGHT (19)
  62.  
  63. struct CalcWindowRec
  64.     {
  65.         MainWindowRec*            MainWindow;
  66.         CodeCenterRec*            CodeCenter;
  67.  
  68.         WinType*                        ScreenID;
  69.         GenericWindowRec*        MyGenericWindow; /* how the window event dispatcher knows us */
  70.         MenuItemType*                MyMenuItem;
  71.         TextEditRec*                Editor;
  72.         long                                LastLine;
  73.         SimpleButtonRec*        EvalButton;
  74.     };
  75.  
  76.  
  77. /* create a new calculator window.  the caller is responsible for registering the */
  78. /* new calculator with the main window. */
  79. CalcWindowRec*            NewCalculatorWindow(struct MainWindowRec* MainWindow,
  80.                                             struct CodeCenterRec* CodeCenter)
  81.     {
  82.         CalcWindowRec*        Window;
  83.  
  84.         CheckPtrExistence(MainWindow);
  85.         CheckPtrExistence(CodeCenter);
  86.         Window = (CalcWindowRec*)AllocPtrCanFail(sizeof(CalcWindowRec),"CalcWindowRec");
  87.         if (Window == NIL)
  88.             {
  89.              FailurePoint1:
  90.                 return NIL;
  91.             }
  92.         Window->MainWindow = MainWindow;
  93.         Window->CodeCenter = CodeCenter;
  94.         Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
  95.             eWindowZoomable,eWindowResizable,WINDOWLEFT,WINDOWTOP,WINDOWWIDTH,WINDOWHEIGHT,
  96.             (void (*)(void*))&CalculatorWindowUpdator,Window);
  97.         if (Window->ScreenID == 0)
  98.             {
  99.              FailurePoint2:
  100.                 ReleasePtr((char*)Window);
  101.                 goto FailurePoint1;
  102.             }
  103.         SetWindowName(Window->ScreenID,"Calculator");
  104.         Window->Editor = NewTextEdit(Window->ScreenID,
  105.             (TEScrollType)(eTEVScrollBar | eTEHScrollBar),GetMonospacedFont(),9,
  106.             -1,(2 * BUTTONTOP) + BUTTONHEIGHT,WINDOWWIDTH + 2,
  107.             WINDOWHEIGHT + 1 - ((2 * BUTTONTOP) + BUTTONHEIGHT));
  108.         if (Window->Editor == NIL)
  109.             {
  110.              FailurePoint3:
  111.                 KillWindow(Window->ScreenID);
  112.                 goto FailurePoint2;
  113.             }
  114.         Window->LastLine = 0;
  115.         Window->EvalButton = NewSimpleButton(Window->ScreenID,"Evaluate",
  116.             BUTTONLEFT,BUTTONTOP,BUTTONWIDTH,BUTTONHEIGHT);
  117.         if (Window->EvalButton == NIL)
  118.             {
  119.              FailurePoint4:
  120.                 DisposeTextEdit(Window->Editor);
  121.                 goto FailurePoint3;
  122.             }
  123.         Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
  124.             (void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&CalculatorWindowDoIdle,
  125.             (void (*)(void*))&CalculatorWindowBecomeActive,
  126.             (void (*)(void*))&CalculatorWindowBecomeInactive,
  127.             (void (*)(void*))&CalculatorWindowJustResized,
  128.             (void (*)(OrdType,OrdType,ModifierFlags,void*))&CalculatorWindowDoMouseDown,
  129.             (void (*)(unsigned char,ModifierFlags,void*))&CalculatorWindowDoKeyDown,
  130.             (void (*)(void*))&CalculatorWindowClose,
  131.             (void (*)(void*))&CalculatorWindowMenuSetup,
  132.             (void (*)(void*,MenuItemType*))&CalculatorWindowDoMenuCommand);
  133.         if (Window->MyGenericWindow == NIL)
  134.             {
  135.              FailurePoint5:
  136.                 DisposeSimpleButton(Window->EvalButton);
  137.                 goto FailurePoint4;
  138.             }
  139.         Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"Calculator",0);
  140.         if (Window->MyMenuItem == NIL)
  141.             {
  142.              FailurePoint6:
  143.                 CheckOutDyingWindow(Window->MyGenericWindow);
  144.                 goto FailurePoint5;
  145.             }
  146.         if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
  147.             Window->ScreenID))
  148.             {
  149.              FailurePoint7:
  150.                 KillMenuItem(Window->MyMenuItem);
  151.                 goto FailurePoint6;
  152.             }
  153.         SetTextEditAutoIndent(Window->Editor,True);
  154.         SetTextEditTabSize(Window->Editor,MainWindowGetTabSize(MainWindow));
  155.         return Window;
  156.     }
  157.  
  158.  
  159. /* dispose of a calculator window.  the calculator notifies the main window that */
  160. /* owns it. */
  161. void                                DisposeCalculatorWindow(CalcWindowRec* Window)
  162.     {
  163.         CheckPtrExistence(Window);
  164.         DeregisterWindowMenuItem(Window->MyMenuItem);
  165.         KillMenuItem(Window->MyMenuItem);
  166.         CheckOutDyingWindow(Window->MyGenericWindow);
  167.         DisposeSimpleButton(Window->EvalButton);
  168.         DisposeTextEdit(Window->Editor);
  169.         KillWindow(Window->ScreenID);
  170.         ReleasePtr((char*)Window);
  171.     }
  172.  
  173.  
  174. void                                CalculatorWindowDoIdle(CalcWindowRec* Window,
  175.                                             MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
  176.                                             ModifierFlags Modifiers)
  177.     {
  178.         CheckPtrExistence(Window);
  179.         TextEditUpdateCursor(Window->Editor);
  180.         if (CheckCursorFlag)
  181.             {
  182.                 if (TextEditIBeamTest(Window->Editor,XLoc,YLoc))
  183.                     {
  184.                         SetIBeamCursor();
  185.                     }
  186.                  else
  187.                     {
  188.                         SetArrowCursor();
  189.                     }
  190.             }
  191.     }
  192.  
  193.  
  194. void                                CalculatorWindowBecomeActive(CalcWindowRec* Window)
  195.     {
  196.         OrdType                        XSize;
  197.         OrdType                        YSize;
  198.  
  199.         CheckPtrExistence(Window);
  200.         EnableTextEditSelection(Window->Editor);
  201.         XSize = GetWindowWidth(Window->ScreenID);
  202.         YSize = GetWindowHeight(Window->ScreenID);
  203.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  204.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
  205.     }
  206.  
  207.  
  208. void                                CalculatorWindowBecomeInactive(CalcWindowRec* Window)
  209.     {
  210.         OrdType                        XSize;
  211.         OrdType                        YSize;
  212.  
  213.         CheckPtrExistence(Window);
  214.         DisableTextEditSelection(Window->Editor);
  215.         XSize = GetWindowWidth(Window->ScreenID);
  216.         YSize = GetWindowHeight(Window->ScreenID);
  217.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  218.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
  219.     }
  220.  
  221.  
  222. void                                CalculatorWindowJustResized(CalcWindowRec* Window)
  223.     {
  224.         OrdType                        XSize;
  225.         OrdType                        YSize;
  226.  
  227.         CheckPtrExistence(Window);
  228.         XSize = GetWindowWidth(Window->ScreenID);
  229.         YSize = GetWindowHeight(Window->ScreenID);
  230.         SetClipRect(Window->ScreenID,0,0,XSize,YSize);
  231.         DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
  232.         SetTextEditPosition(Window->Editor,-1,(2 * BUTTONTOP) + BUTTONHEIGHT,
  233.             XSize + 2,YSize + 1 - ((2 * BUTTONTOP) + BUTTONHEIGHT));
  234.     }
  235.  
  236.  
  237. void                                CalculatorWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
  238.                                             ModifierFlags Modifiers, CalcWindowRec* Window)
  239.     {
  240.         CheckPtrExistence(Window);
  241.         if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
  242.             && (XLoc < GetWindowWidth(Window->ScreenID))
  243.             && (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
  244.             && (YLoc < GetWindowHeight(Window->ScreenID)))
  245.             {
  246.                 UserGrowWindow(Window->ScreenID,XLoc,YLoc);
  247.                 CalculatorWindowJustResized(Window);
  248.             }
  249.         else if (TextEditHitTest(Window->Editor,XLoc,YLoc))
  250.             {
  251.                 TextEditDoMouseDown(Window->Editor,XLoc,YLoc,Modifiers);
  252.             }
  253.         else if (SimpleButtonHitTest(Window->EvalButton,XLoc,YLoc))
  254.             {
  255.                 if (SimpleButtonMouseDown(Window->EvalButton,XLoc,YLoc,NIL,NIL))
  256.                     {
  257.                         CalculatorWindowDoCalculation(Window);
  258.                     }
  259.             }
  260.     }
  261.  
  262.  
  263. void                                CalculatorWindowDoKeyDown(unsigned char KeyCode,
  264.                                             ModifierFlags Modifiers, CalcWindowRec* Window)
  265.     {
  266.         CheckPtrExistence(Window);
  267.         TextEditDoKeyPressed(Window->Editor,KeyCode,Modifiers);
  268.     }
  269.  
  270.  
  271. void                                CalculatorWindowClose(CalcWindowRec* Window)
  272.     {
  273.         CheckPtrExistence(Window);
  274.         /* notification of closing is here and not in dispose because FunctionWindow */
  275.         /* calls dispose, so it knows that we are dying, but this routine handles */
  276.         /* a user close, which FunctionWindow doesn't know about */
  277.         MainWindowCalculatorClosingNotify(Window->MainWindow,Window);
  278.         DisposeCalculatorWindow(Window);
  279.     }
  280.  
  281.  
  282. void                                CalculatorWindowUpdator(CalcWindowRec* Window)
  283.     {
  284.         OrdType            XSize;
  285.         OrdType            YSize;
  286.  
  287.         CheckPtrExistence(Window);
  288.         TextEditFullRedraw(Window->Editor);
  289.         RedrawSimpleButton(Window->EvalButton);
  290.         XSize = GetWindowWidth(Window->ScreenID);
  291.         YSize = GetWindowHeight(Window->ScreenID);
  292.         SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
  293.         DrawBitmap(Window->ScreenID,XSize-15,YSize-15,
  294.             GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
  295.     }
  296.  
  297.  
  298. void                                CalculatorWindowMenuSetup(CalcWindowRec* Window)
  299.     {
  300.         CheckPtrExistence(Window);
  301.         MainWindowEnableGlobalMenus(Window->MainWindow);
  302.         EnableMenuItem(mPaste);
  303.         ChangeItemName(mPaste,"Paste Text");
  304.         if (TextEditIsThereValidSelection(Window->Editor))
  305.             {
  306.                 EnableMenuItem(mCut);
  307.                 ChangeItemName(mCut,"Cut Text");
  308.                 EnableMenuItem(mCopy);
  309.                 ChangeItemName(mCopy,"Copy Text");
  310.                 EnableMenuItem(mClear);
  311.                 ChangeItemName(mClear,"Clear Text");
  312.             }
  313.         EnableMenuItem(mShiftLeft);
  314.         EnableMenuItem(mShiftRight);
  315.         EnableMenuItem(mBalanceParens);
  316.         EnableMenuItem(mSelectAll);
  317.         ChangeItemName(mSelectAll,"Select All Text");
  318.         if (TextEditCanWeUndo(Window->Editor))
  319.             {
  320.                 EnableMenuItem(mUndo);
  321.                 ChangeItemName(mUndo,"Undo Text Change");
  322.             }
  323.         ChangeItemName(mCloseFile,"Close Calculator");
  324.         EnableMenuItem(mCloseFile);
  325.         EnableMenuItem(mEvaluateCalc);
  326.         SetItemCheckmark(Window->MyMenuItem);
  327.         EnableMenuItem(mDisassembleFunction);
  328.     }
  329.  
  330.  
  331. void                                CalculatorWindowDoMenuCommand(CalcWindowRec* Window,
  332.                                             MenuItemType* MenuItem)
  333.     {
  334.         CheckPtrExistence(Window);
  335.         if (MainWindowDoGlobalMenuItem(Window->MainWindow,MenuItem))
  336.             {
  337.             }
  338.         else if (MenuItem == mPaste)
  339.             {
  340.                 TextEditDoMenuPaste(Window->Editor);
  341.             }
  342.         else if (MenuItem == mCut)
  343.             {
  344.                 TextEditDoMenuCut(Window->Editor);
  345.             }
  346.         else if (MenuItem == mCopy)
  347.             {
  348.                 TextEditDoMenuCopy(Window->Editor);
  349.             }
  350.         else if (MenuItem == mClear)
  351.             {
  352.                 TextEditDoMenuClear(Window->Editor);
  353.             }
  354.         else if (MenuItem == mSelectAll)
  355.             {
  356.                 TextEditDoMenuSelectAll(Window->Editor);
  357.             }
  358.         else if (MenuItem == mUndo)
  359.             {
  360.                 TextEditDoMenuUndo(Window->Editor);
  361.             }
  362.         else if (MenuItem == mCloseFile)
  363.             {
  364.                 CalculatorWindowClose(Window);
  365.             }
  366.         else if (MenuItem == mShiftLeft)
  367.             {
  368.                 TextEditShiftSelectionLeftOneTab(Window->Editor);
  369.             }
  370.         else if (MenuItem == mShiftRight)
  371.             {
  372.                 TextEditShiftSelectionRightOneTab(Window->Editor);
  373.             }
  374.         else if (MenuItem == mBalanceParens)
  375.             {
  376.                 TextEditBalanceParens(Window->Editor);
  377.             }
  378.         else if (MenuItem == mEvaluateCalc)
  379.             {
  380.                 CalculatorWindowDoCalculation(Window);
  381.             }
  382.         else if (MenuItem == mDisassembleFunction)
  383.             {
  384.                 char*                                Blob;
  385.                 PcodeRec*                        FuncCode;
  386.                 CompileErrors                Error;
  387.                 long                                LineNumber;
  388.                 DataTypes                        ReturnType;
  389.                 char*                                DisassemblyText;
  390.  
  391.                 /* prepare the text blob to be evaluated */
  392.                 if (!TextEditIsThereValidSelection(Window->Editor))
  393.                     {
  394.                         if (Window->LastLine > GetTextEditNumLines(Window->Editor))
  395.                             {
  396.                                 Window->LastLine = GetTextEditNumLines(Window->Editor);
  397.                             }
  398.                         SetTextEditSelection(Window->Editor,Window->LastLine,0,
  399.                             GetTextEditNumLines(Window->Editor),0);
  400.                     }
  401.                 Blob = TextEditGetSelection(Window->Editor);
  402.                 if (Blob == NIL)
  403.                     {
  404.                      FailurePoint1:
  405.                         AlertHalt("There is not enough memory available to compile "
  406.                             "the expression.",NIL);
  407.                         return;
  408.                     }
  409.  
  410.                 /* perform compilation */
  411.                 EXECUTE(FuncCode = NIL;)
  412.                 Error = CompileSpecialFunction(NIL/*no arguments*/,0/*noargs*/,&LineNumber,
  413.                     &ReturnType,Blob/*text*/,&FuncCode);
  414.                 ReleasePtr(Blob);
  415.                 if (Error != eCompileNoError)
  416.                     {
  417.                         ERROR(FuncCode != NIL,PRERR(ForceAbort,"CalculatorWindowDoMenuCommand:  "
  418.                             "compile failed, but function is not NIL."));
  419.                         SetTextEditSelection(Window->Editor,
  420.                             GetTextEditSelectStartLine(Window->Editor) + LineNumber,0,
  421.                             GetTextEditSelectStartLine(Window->Editor) + LineNumber + 1,0);
  422.                         TextEditShowSelection(Window->Editor);
  423.                         AlertHalt("A compile error occurred:  _",GetCompileErrorString(Error));
  424.                         return;
  425.                     }
  426.  
  427.                 /* obtain the disassembly */
  428.                 DisassemblyText = DisassemblePcode(FuncCode,'\x0a');
  429.                 DisposePcode(FuncCode);
  430.                 if (DisassemblyText == NIL)
  431.                     {
  432.                         AlertHalt("There is not enough memory available to disassemble "
  433.                             "the expression.",NIL);
  434.                         return;
  435.                     }
  436.  
  437.                 /* show it */
  438.                 if (NewDisassemblyWindow(DisassemblyText,Window->MainWindow) == NIL)
  439.                     {
  440.                         AlertHalt("There is not enough memory available to "
  441.                             "show the disassembly window.",NIL);
  442.                     }
  443.                 ReleasePtr(DisassemblyText);
  444.             }
  445.         else
  446.             {
  447.                 EXECUTE(PRERR(AllowResume,"CalculatorWindowDoMenuCommand:  unknown menu command"));
  448.             }
  449.     }
  450.  
  451.  
  452. /* perform evaluation.  if there is a selection, then evaluate */
  453. /* the selection, otherwise evaluate from last point */
  454. void                                CalculatorWindowDoCalculation(CalcWindowRec* Window)
  455.     {
  456.         char*                                Blob;
  457.         PcodeRec*                        FuncCode;
  458.         CompileErrors                Error;
  459.         long                                LineNumber;
  460.         DataTypes                        ReturnType;
  461.         ParamStackRec*            ParamList;
  462.         EvalErrors                    OtherError;
  463.         OpcodeRec*                    ErrorOpcode;
  464.         long                                OffendingInstruction;
  465.         char*                                Number;
  466.         char*                                Statement;
  467.         MyBoolean                        MemoryErrorOccurred;
  468.  
  469.         CheckPtrExistence(Window);
  470.  
  471.         /* bring the world up to date */
  472.         if (!MainWindowMakeUpToDateFunctions(Window->MainWindow))
  473.             {
  474.                 return;
  475.             }
  476.  
  477.         /* prepare the text blob to be evaluated */
  478.         if (!TextEditIsThereValidSelection(Window->Editor))
  479.             {
  480.                 if (Window->LastLine > GetTextEditNumLines(Window->Editor))
  481.                     {
  482.                         Window->LastLine = GetTextEditNumLines(Window->Editor);
  483.                     }
  484.                 SetTextEditSelection(Window->Editor,Window->LastLine,0,
  485.                     GetTextEditNumLines(Window->Editor),0);
  486.             }
  487.         Blob = TextEditGetSelection(Window->Editor);
  488.         if (Blob == NIL)
  489.             {
  490.              FailurePoint1:
  491.                 AlertHalt("There is not enough memory available to compile the expression.",NIL);
  492.                 return;
  493.             }
  494.  
  495.         /* perform compilation */
  496.         EXECUTE(FuncCode = NIL;)
  497.         Error = CompileSpecialFunction(NIL/*no arguments*/,0/*noargs*/,&LineNumber,
  498.             &ReturnType,Blob/*text*/,&FuncCode);
  499.         ReleasePtr(Blob);
  500.         if (Error != eCompileNoError)
  501.             {
  502.                 ERROR(FuncCode != NIL,PRERR(ForceAbort,
  503.                     "CalculatorWindowDoCalculation:  compile failed, but function is not NIL."));
  504.                 SetTextEditSelection(Window->Editor,GetTextEditSelectStartLine(Window->Editor)
  505.                     + LineNumber,0,GetTextEditSelectStartLine(Window->Editor) + LineNumber + 1,0);
  506.                 TextEditShowSelection(Window->Editor);
  507.                 AlertHalt("A compile error occurred:  _",GetCompileErrorString(Error));
  508.                 return;
  509.             }
  510.  
  511.         /* try to evaluate the code */
  512.         ParamList = NewParamStack();
  513.         if (ParamList == NIL)
  514.             {
  515.              SecondFailurePoint1:
  516.                 DisposePcode(FuncCode);
  517.                 AlertHalt("There is not enough memory available to evaluate the expression.",NIL);
  518.                 return;
  519.             }
  520.         /* add a space for the return value */
  521.         if (!AddIntegerToStack(ParamList,0))
  522.             {
  523.              SecondFailurePoint2:
  524.                 goto SecondFailurePoint1;
  525.             }
  526.         /* executing the actual code */
  527.         OtherError = EvaluatePcode(ParamList,FuncCode,
  528.             Window->CodeCenter,&ErrorOpcode,&OffendingInstruction,Window->MainWindow,
  529.             &MainWindowGetSampleLeftCopy,&MainWindowGetSampleRightCopy,
  530.             &MainWindowGetSampleMonoCopy,&MainWindowGetWaveTableFrameCount,
  531.             &MainWindowGetWaveTableTableCount,&MainWindowGetWaveTableArray);
  532.         if (OtherError != eEvalNoError)
  533.             {
  534.                 char*                    FuncNameString;
  535.                 MyBoolean            SuccessFlag;
  536.  
  537.                 /* present error message */
  538.                 SuccessFlag = False;
  539.                 if (GetOpcodeFromPcode(FuncCode) == ErrorOpcode)
  540.                     {
  541.                         /* our function, not a library function */
  542.                         FuncNameString = StringToBlockCopy("<anonymous>");
  543.                     }
  544.                  else
  545.                     {
  546.                         /* it is a library function, so look it up */
  547.                         FuncNameString = StringToBlockCopy(GetFunctionName(
  548.                             GetFunctionFromOpcode(Window->CodeCenter,ErrorOpcode)));
  549.                     }
  550.                 if (FuncNameString != NIL)
  551.                     {
  552.                         char*                    Key;
  553.  
  554.                         Key = StringToBlockCopy("_");
  555.                         if (Key != NIL)
  556.                             {
  557.                                 char*                    BaseMessage;
  558.  
  559.                                 BaseMessage = StringFromRaw("Error in function _, instruction _:  _");
  560.                                 if (BaseMessage != NIL)
  561.                                     {
  562.                                         char*                    FixedMessage1;
  563.  
  564.                                         FixedMessage1 = ReplaceBlockCopy(BaseMessage,Key,FuncNameString);
  565.                                         if (FixedMessage1 != NIL)
  566.                                             {
  567.                                                 char*                    NumberStr;
  568.  
  569.                                                 NumberStr = IntegerToString(OffendingInstruction);
  570.                                                 if (NumberStr != NIL)
  571.                                                     {
  572.                                                         char*                    FixedMessage2;
  573.  
  574.                                                         FixedMessage2 = ReplaceBlockCopy(FixedMessage1,Key,NumberStr);
  575.                                                         if (FixedMessage2 != NIL)
  576.                                                             {
  577.                                                                 AlertHalt(FixedMessage2,GetPcodeErrorMessage(OtherError));
  578.                                                                 SuccessFlag = True;
  579.                                                                 ReleasePtr(FixedMessage2);
  580.                                                             }
  581.                                                         ReleasePtr(NumberStr);
  582.                                                     }
  583.                                                 ReleasePtr(FixedMessage1);
  584.                                             }
  585.                                         ReleasePtr(BaseMessage);
  586.                                     }
  587.                                 ReleasePtr(Key);
  588.                             }
  589.                         ReleasePtr(FuncNameString);
  590.                     }
  591.                 if (!SuccessFlag)
  592.                     {
  593.                         AlertHalt("There is not enough memory available to show "
  594.                             "the compile error message.",NIL);
  595.                     }
  596.                 DisposeParamStack(ParamList);
  597.                 DisposePcode(FuncCode);
  598.                 return;
  599.             }
  600.  
  601.         /* add new data to window */
  602.         MemoryErrorOccurred = False;
  603.         TextEditAppendLineInteraction(Window->Editor,NIL);
  604.         switch (ReturnType)
  605.             {
  606.                 default:
  607.                     EXECUTE(PRERR(ForceAbort,"CalculatorWindowDoCalculation:  unknown type"));
  608.                     break;
  609.                 case eBoolean:
  610.                     /* prepare value */
  611.                     if (GetStackInteger(ParamList,0) != 0)
  612.                         {
  613.                             Number = StringToBlockCopy("true");
  614.                         }
  615.                      else
  616.                         {
  617.                             Number = StringToBlockCopy("false");
  618.                         }
  619.                     Statement = StringToBlockCopy("returns boolean:  _");
  620.                     /* put value in editor */
  621.                  ScalarMakePoint:
  622.                     if (Number != NIL)
  623.                         {
  624.                             if (Statement != NIL)
  625.                                 {
  626.                                     char*                Key;
  627.  
  628.                                     Key = StringToBlockCopy("_");
  629.                                     if (Key != NIL)
  630.                                         {
  631.                                             char*                Fixer;
  632.  
  633.                                             Fixer = ReplaceBlockCopy(Statement,Key,Number);
  634.                                             if (Fixer != NIL)
  635.                                                 {
  636.                                                     TextEditAppendLineInteraction(Window->Editor,Fixer);
  637.                                                     ReleasePtr(Fixer);
  638.                                                 }
  639.                                              else
  640.                                                 {
  641.                                                     MemoryErrorOccurred = True;
  642.                                                 }
  643.                                             ReleasePtr(Key);
  644.                                         }
  645.                                      else
  646.                                         {
  647.                                             MemoryErrorOccurred = True;
  648.                                         }
  649.                                 }
  650.                              else
  651.                                 {
  652.                                     MemoryErrorOccurred = True;
  653.                                 }
  654.                         }
  655.                      else
  656.                         {
  657.                             MemoryErrorOccurred = True;
  658.                         }
  659.                     /* dispose values */
  660.                     if (Number != NIL)
  661.                         {
  662.                             ReleasePtr(Number);
  663.                         }
  664.                     if (Statement != NIL)
  665.                         {
  666.                             ReleasePtr(Statement);
  667.                         }
  668.                     break;
  669.                 case eInteger:
  670.                     Number = IntegerToString(GetStackInteger(ParamList,0));
  671.                     Statement = StringToBlockCopy("returns integer:  _");
  672.                     goto ScalarMakePoint;
  673.                 case eFixed:
  674.                     Number = LongDoubleToString(
  675.                         largefixed2double(GetStackInteger(ParamList,0)),11,1e-9,1e6);
  676.                     Statement = StringToBlockCopy("returns fixed:  _");
  677.                     goto ScalarMakePoint;
  678.                 case eFloat:
  679.                     Number = LongDoubleToString(GetStackFloat(ParamList,0),7,1e-4,1e6);
  680.                     Statement = StringToBlockCopy("returns float:  _");
  681.                     goto ScalarMakePoint;
  682.                 case eDouble:
  683.                     Number = LongDoubleToString(GetStackLongDouble(ParamList,0),15,1e-4,1e6);
  684.                     Statement = StringToBlockCopy("returns double:  _");
  685.                     goto ScalarMakePoint;
  686.                 case eArrayOfBoolean:
  687.                     Statement = StringToBlockCopy("returns array of boolean:");
  688.                     goto ArrayMakePoint;
  689.                 case eArrayOfInteger:
  690.                     Statement = StringToBlockCopy("returns array of integer:");
  691.                     goto ArrayMakePoint;
  692.                 case eArrayOfFixed:
  693.                     Statement = StringToBlockCopy("returns array of fixed:");
  694.                     goto ArrayMakePoint;
  695.                 case eArrayOfFloat:
  696.                     Statement = StringToBlockCopy("returns array of float:");
  697.                     goto ArrayMakePoint;
  698.                 case eArrayOfDouble:
  699.                     /* construct statement */
  700.                     Statement = StringToBlockCopy("returns array of double:");
  701.                  ArrayMakePoint:
  702.                     if (Statement != NIL)
  703.                         {
  704.                             void*                    Array;
  705.  
  706.                             TextEditAppendLineInteraction(Window->Editor,Statement);
  707.                             ReleasePtr(Statement);
  708.                             Array = GetStackArray(ParamList,0);
  709.                             if (Array == NIL)
  710.                                 {
  711.                                     char*                    Thang;
  712.  
  713.                                     Thang = StringToBlockCopy("NIL");
  714.                                     if (Thang != NIL)
  715.                                         {
  716.                                             TextEditAppendLineInteraction(Window->Editor,Thang);
  717.                                             ReleasePtr(Thang);
  718.                                         }
  719.                                      else
  720.                                         {
  721.                                             MemoryErrorOccurred = True;
  722.                                         }
  723.                                 }
  724.                              else
  725.                                 {
  726.                                     long                    Scan;
  727.                                     long                    ElementSize;
  728.                                     long                    Limit;
  729.  
  730.                                     switch (ReturnType)
  731.                                         {
  732.                                             case eArrayOfBoolean:
  733.                                                 ElementSize = sizeof(char);
  734.                                                 break;
  735.                                             case eArrayOfInteger:
  736.                                                 ElementSize = sizeof(long);
  737.                                                 break;
  738.                                             case eArrayOfFixed:
  739.                                                 ElementSize = sizeof(largefixedsigned);
  740.                                                 break;
  741.                                             case eArrayOfFloat:
  742.                                                 ElementSize = sizeof(float);
  743.                                                 break;
  744.                                             case eArrayOfDouble:
  745.                                                 ElementSize = sizeof(double);
  746.                                                 break;
  747.                                             default:
  748.                                                 EXECUTE(PRERR(ForceAbort,
  749.                                                     "CalculatorWindowDoCalculation:  type filter failure"));
  750.                                                 break;
  751.                                         }
  752.                                     Limit = PtrSize((char*)Array) / ElementSize;
  753.                                     for (Scan = 0; (Scan < Limit) && !MemoryErrorOccurred
  754.                                         && !RelinquishCPUJudiciouslyCheckCancel(); Scan += 1)
  755.                                         {
  756.                                             char*                    LineNum;
  757.  
  758.                                             LineNum = IntegerToString(Scan);
  759.                                             if (LineNum != NIL)
  760.                                                 {
  761.                                                     char*                    Data;
  762.  
  763.                                                     switch (ReturnType)
  764.                                                         {
  765.                                                             case eArrayOfBoolean:
  766.                                                                 if (((char*)Array)[Scan])
  767.                                                                     {
  768.                                                                         Data = StringToBlockCopy("true");
  769.                                                                     }
  770.                                                                  else
  771.                                                                     {
  772.                                                                         Data = StringToBlockCopy("false");
  773.                                                                     }
  774.                                                                 break;
  775.                                                             case eArrayOfInteger:
  776.                                                                 Data = IntegerToString(((long*)Array)[Scan]);
  777.                                                                 break;
  778.                                                             case eArrayOfFixed:
  779.                                                                 Data = LongDoubleToString(largefixed2double(
  780.                                                                     ((largefixedsigned*)Array)[Scan]),11,1e-9,1e6);
  781.                                                                 break;
  782.                                                             case eArrayOfFloat:
  783.                                                                 Data = LongDoubleToString(((float*)
  784.                                                                     Array)[Scan],7,1e-4,1e6);
  785.                                                                 break;
  786.                                                             case eArrayOfDouble:
  787.                                                                 Data = LongDoubleToString(((double*)
  788.                                                                     Array)[Scan],15,1e-4,1e6);
  789.                                                                 break;
  790.                                                             default:
  791.                                                                 EXECUTE(PRERR(ForceAbort,
  792.                                                                     "CalculatorWindowDoCalculation:  type filter failure"));
  793.                                                                 break;
  794.                                                         }
  795.                                                     if (Data != NIL)
  796.                                                         {
  797.                                                             char*                LineNumCopy;
  798.  
  799.                                                             if (PtrSize(LineNum) > 16 - 1)
  800.                                                                 {
  801.                                                                     LineNumCopy = CopyPtr(LineNum);
  802.                                                                 }
  803.                                                              else
  804.                                                                 {
  805.                                                                     long                Index;
  806.  
  807.                                                                     LineNumCopy = AllocPtrCanFail(16,"LineNumCopy");
  808.                                                                     if (LineNumCopy != NIL)
  809.                                                                         {
  810.                                                                             for (Index = 0; Index < 16; Index += 1)
  811.                                                                                 {
  812.                                                                                     LineNumCopy[Index] = 32;
  813.                                                                                 }
  814.                                                                             CopyData(LineNum,LineNumCopy,PtrSize(LineNum));
  815.                                                                             LineNumCopy[PtrSize(LineNum)] = ':';
  816.                                                                         }
  817.                                                                 }
  818.                                                             if (LineNumCopy != NIL)
  819.                                                                 {
  820.                                                                     char*                    Total;
  821.  
  822.                                                                     Total = ConcatBlockCopy(LineNumCopy,Data);
  823.                                                                     if (Total != NIL)
  824.                                                                         {
  825.                                                                             TextEditAppendLineInteraction(Window->Editor,Total);
  826.                                                                             ReleasePtr(Total);
  827.                                                                         }
  828.                                                                      else
  829.                                                                         {
  830.                                                                             MemoryErrorOccurred = True;
  831.                                                                         }
  832.                                                                     ReleasePtr(LineNumCopy);
  833.                                                                 }
  834.                                                              else
  835.                                                                 {
  836.                                                                     MemoryErrorOccurred = True;
  837.                                                                 }
  838.                                                             ReleasePtr(Data);
  839.                                                         }
  840.                                                      else
  841.                                                         {
  842.                                                             MemoryErrorOccurred = True;
  843.                                                         }
  844.                                                     ReleasePtr(LineNum);
  845.                                                 }
  846.                                              else
  847.                                                 {
  848.                                                     MemoryErrorOccurred = True;
  849.                                                 }
  850.                                         }
  851.                                 }
  852.                         }
  853.                      else
  854.                         {
  855.                             MemoryErrorOccurred = True;
  856.                         }
  857.                     break;
  858.             }
  859.         /* add final terminating thing */
  860.         TextEditAppendLineInteraction(Window->Editor,NIL);
  861.         TextEditShowSelection(Window->Editor);
  862.         if (MemoryErrorOccurred)
  863.             {
  864.                 AlertHalt("There is not enough memory available to completely display the "
  865.                     "results of evaluating the function.",NIL);
  866.             }
  867.  
  868.         /* remember new last line */
  869.         Window->LastLine = GetTextEditNumLines(Window->Editor) - 1;
  870.  
  871.         /* dispose of stuff */
  872.         DisposeParamStack(ParamList);
  873.         DisposePcode(FuncCode);
  874.     }
  875.